package com.singfan.common.db;

import com.singfan.common.util.BeanUtil;
import com.singfan.common.util.StringUtil;
import com.singfan.common.db.annotation.Column;
import com.singfan.common.db.annotation.Ignore;
import com.singfan.common.db.annotation.Primarykey;
import com.singfan.common.db.annotation.Table;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 数据库工具类
 * Author: HanSongHe
 * Date: 15-7-14 下午5:08
 */
public class DbUtil {
    private static final String PRIMARY_KEY_SEPARATOR = ";";

    /**
     * 将类名转换成数据库的表名
     * @param beanClassType 类的类型信息
     * @return 数据库的表名
     */
    public static String className2TableName(Class beanClassType){
        String tableName;
        Table table = (Table) beanClassType.getAnnotation(Table.class);
        if(table != null){
            tableName = table.name();
        }
        else{
            String className = beanClassType.getSimpleName();
            tableName = StringUtil.javaName2CommonName(className);
        }

        return tableName;
    }

    /**
     * 将类的字段名转换成数据库表的列名
     * @param field 类的字段名
     * @return 表的字段名
     */
    public static String fieldName2ColumnName(Field field){
        String columnName;

        Column column = field.getAnnotation(Column.class);
        if(column != null){
            columnName = column.name();
        }
        else{
            String fieldName = field.getName();
            columnName = StringUtil.javaName2CommonName(fieldName);
        }

        return columnName;
    }

    /**
     * 判断此字段是否为主键
     * @param field 字段信息
     * @return true:是   false:否
     */
    public static boolean isPrimaryKeyFiled(Field field){
        boolean result = false;
        Primarykey primarykey = field.getAnnotation(Primarykey.class);
        if(primarykey != null){
            result = true;
        }
        return result;
    }

    /**
     * 判断此字段是否为需要忽略的字段
     * @param field 字段信息
     * @return true:是   false:否
     */
    public static boolean isIgnoreFiled(Field field){
        boolean result = false;
        Ignore ignore = field.getAnnotation(Ignore.class);
        if(ignore != null){
            result = true;
        }
        return result;
    }

    /**
     * 将ResultSet中的数据填充到Bean对象中
     * @param object Bean对象
     * @param resultSet ResultSet对象
     * @throws SQLException
     */
    public static void fillBean(Object object, ResultSet resultSet) throws SQLException {
        List<Field> fieldList = BeanUtil.getBeanFieldList(object.getClass());
        for(Field field : fieldList){
            boolean isIgnore = DbUtil.isIgnoreFiled(field);
            if(!isIgnore){
                String fieldName = field.getName();
                String columnName = DbUtil.fieldName2ColumnName(field);
                Object filedValue = resultSet.getObject(columnName);
                BeanUtil.setBeanFieldValue(object, fieldName, filedValue);
            }
        }
    }

    /**
     * 将数组类型的参数转换成列表类型的参数
     * @param params 组类型的参数
     * @return 列表类型的参数
     */
    public static List<Object> params2paramList(Object[] params){
        List<Object> paramList = null;

        if(params != null && params.length > 0){
            paramList = new ArrayList<>();
            for(Object param : params){
                paramList.add(param);
            }
        }

        return paramList;
    }

    /**
     * 将列表类型的参数转换成一个字符串的形式
     * @param params 组类型的参数
     * @return 列表类型的参数
     */
    public static String getSqlParamInfo(List<Object> params){
        StringBuilder stringBuilder = new StringBuilder("[");

        if(params != null && params.size() > 0){
            for(int i = 0; i < params.size(); i++){
                Object param = params.get(i);
                if(i == 0){
                    stringBuilder.append(param);
                }
                else{
                    stringBuilder.append(",");
                    stringBuilder.append(param);
                }
            }
        }

        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    /**
     * 将数据库主键集合转换成一个字符串
     * @param primaryKeyArr 主键集合
     * @return 字符串
     */
//    public static String primarykeys2String(Object... primaryKeyArr){
//        String primarykeys = "";
//
//        if (primaryKeyArr != null && primaryKeyArr.length > 0){
//            for (Object primaryKey : primaryKeyArr){
//                primarykeys += primaryKey.toString() + PRIMARY_KEY_SEPARATOR;
//            }
//
//            primarykeys = primarykeys.substring(0, primarykeys.length() - 1);
//        }
//
//        return primarykeys;
//    }

    /**
     * 将数据库主键集合转换成一个字符串
     * @param primaryKeySet 主键集合
     * @return 字符串
     */
    public static String primaryKeySet2String(Object bean, Set<String> primaryKeySet){
        String primarykeys = "";

        for(String primaryKey : primaryKeySet){
            Object fieldValue = BeanUtil.getBeanFieldValue(bean, primaryKey);
            primarykeys += fieldValue.toString() + PRIMARY_KEY_SEPARATOR;
        }

        if (!StringUtil.isNullOrEmpty(primarykeys)){
            primarykeys = primarykeys.substring(0, primarykeys.length() - 1);
        }

        return primarykeys;
    }

    /**
     * 将数据库主键集合转换成一个字符串
     * @param primaryKeyList 主键集合
     * @return 字符串
     */
    public static String primaryKeyList2String(List<Object> primaryKeyList){
        String primarykeys = "";

        for(Object primaryKey : primaryKeyList){
            primarykeys += primaryKey.toString() + PRIMARY_KEY_SEPARATOR;
        }

        if (!StringUtil.isNullOrEmpty(primarykeys)){
            primarykeys = primarykeys.substring(0, primarykeys.length() - 1);
        }

        return primarykeys;
    }

    /**
     * 将数据库主键集合的字符串形式转换成一个列表
     * @param primarykeys 主键集合的字符串形式
     * @return 主键列表
     */
    public static List<String> primaryKeys2List(String primarykeys){
        List<String> primarykeyList = new ArrayList<>();

        if (!StringUtil.isNullOrEmpty(primarykeys)){
            String[] primaryKeyArr = primarykeys.split(PRIMARY_KEY_SEPARATOR);
            if (primaryKeyArr != null && primaryKeyArr.length > 0){
                for (String primaryKey : primaryKeyArr){
                    primarykeyList.add(primaryKey);
                }
            }
        }

        return primarykeyList;
    }
}
